# -*- coding:utf-8 -*-
# created on 2017/3/6
# 

from mathsolver.functions.base import *
from mathsolver.functions.base.base import new_latex
from mathsolver.functions.base.xl_objects import BaseVectorValue, BaseVectorTriangle
from sympy import Abs, Mul, symbols, cos, pi
from mathsolver.functions.xiangliang.Vector_Fundamental import vector_xiangs


# 向量方程更新
class XLEqUpdate(BaseFunction):
    """
    已知向量\\overrightarrow{a}=(4,2),向量\\overrightarrow{b}=(x,3),\\overrightarrow{a}∥\\overrightarrow{b},则x=()
    """
    def solver(self, *args):
        vectoreq = args[0].sympify()
        assert isinstance(args[0], BaseVectorEq)
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        eq = vectoreq
        if len(eq) == 3:
            expr1 = eq[0] - eq[2]
            p1 = r'Abs\(vector\(.{1,2}?\)\)'
            m1 = re.findall(p1, str(expr1))
            veqs.append([eq[0], eq[2]])
            if len(m1) == 1:
                new_expr1 = expr1
                m1 = m1[0]
                m1 = sympify(m1)
                name1 = m1.args[0].args[0]
                name1 = str('Abs_') + str(name1)
                name1 = sympify(name1)
                new_expr1 = new_expr1.subs({m1: name1})
                solutions1 = solve(new_expr1, name1)
                if len(solutions1) == 1:
                    solution1 = solutions1[0]
                    xiangs1 = vector_xiangs(solution1)
                    if not xiangs1:
                        answer[str(name1)] = solution1
            expr2 = eq[1] - eq[2]
            veqs.append([eq[1], eq[2]])
            p2 = r'Abs\(vector\(.{1,2}?\)\)'
            m2 = re.findall(p2, str(expr2))
            solutions2 = None
            if len(m2) == 1:
                new_expr2 = expr2
                m2 = m2[0]
                m2 = sympify(m2)
                name2 = m2.args[0].args[0]
                name2 = str('Abs_') + str(name2)
                name2 = sympify(name2)
                new_expr2 = new_expr2.subs({m2: name2})
                solutions2 = solve(new_expr2, name2)
                if len(solutions2) == 1:
                    solution2 = solutions2[0]
                    xiangs2 = vector_xiangs(solution2)
                    if not xiangs2:
                        answer[str(name2)] = solution2
            expr3 = eq[0] - eq[1]
            veqs.append([eq[1], eq[2]])
            p3 = r'Abs\(vector\(.{1,2}?\)\)'
            m3 = re.findall(p3, str(expr3))
            if len(m3) == 1:
                new_expr3 = expr3
                m3 = m3[0]
                m3 = sympify(m3)
                name3 = m3.args[0].args[0]
                name3 = str('Abs_') + str(name3)
                name3 = sympify(name3)
                new_expr3 = new_expr3.subs({m2: name3})
                solutions3 = solve(new_expr3, name3)
                if len(solutions3) == 1:
                    solution3 = solutions2[0]
                    xiangs3 = vector_xiangs(solution3)
                    if not xiangs3:
                        answer[str(name3)] = solution3
        else:
            if isinstance(eq[1], (list, tuple)):
                expr = eq[0]
                p = r'vector\(.{1,2}?\)'
                m = re.findall(p, str(expr))
                if len(m) == 1:
                    m = m[0]
                    m = sympify(m)
                    name = m.args[0]
                    if len(str(name)) != 2:
                        name = str('Axis_') + str(name)
                        answer[name] = eq[1]
                    else:
                        veqs.append(eq)
                else:
                    veqs.append(eq)
            else:
                expr = eq[0] - eq[1]
                veqs.append(eq)
                p = r'Abs\(vector\(.{1,2}?\)\)'
                m = re.findall(p, str(expr))
                if len(m) == 1:
                    new_expr = expr
                    m = m[0]
                    m = sympify(m)
                    name = m.args[0].args[0]
                    if len(str(name)) != 2:
                        name = str('Abs_') + str(name)
                        name = sympify(name)
                        new_expr = new_expr.subs({m: name})
                        solutions = solve(new_expr, name)
                        if len(solutions) == 1:
                            solution = solutions[0]
                            xiangs = vector_xiangs(solution)
                            if not xiangs:
                                answer[str(name)] = solution
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 向量不等式更新
class XLIneqUpdate(BaseFunction):
    def solver(self, *args):
        ineq = args[0].sympify()
        assert isinstance(args[0], BaseIneq)
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append(ineq)
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 向量方程组更新
class XLEqsUpdate(BaseFunction):
    """
    已知向量\\overrightarrow{a},\\overrightarrow{b}夹角为45°,
    |\\overrightarrow{a}|=1,|2\\overrightarrow{a}-\\overrightarrow{b}|=\\sqrt{10},则|\\overrightarrow{b}|=().
    """
    def solver(self, *args):
        vectoreqs = args[0].sympify()
        assert isinstance(vectoreqs, list)
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        for eq in vectoreqs:
            if len(eq) == 3:
                expr1 = eq[0] - eq[2]
                p1 = r'Abs\(vector\(.{1,2}?\)\)'
                m1 = re.findall(p1, str(expr1))
                if len(m1) == 1:
                    new_expr1 = expr1
                    m1 = m1[0]
                    m1 = sympify(m1)
                    name1 = m1.args[0].args[0]
                    name1 = str('Abs_') + str(name1)
                    name1 = sympify(name1)
                    new_expr1 = new_expr1.subs({m1: name1})
                    solutions1 = solve(new_expr1, name1)
                    if len(solutions1) == 1:
                        solution1 = solutions1[0]
                        xiangs1 = vector_xiangs(solution1)
                        if not xiangs1:
                            answer[str(name1)] = solution1
                            veqs.append([eq[0], eq[2]])
                        else:
                            veqs.append([eq[0], eq[2]])
                    else:
                        veqs.append([eq[0], eq[1]])
                else:
                    veqs.append([eq[0], eq[2]])
                expr2 = eq[1] - eq[2]
                p2 = r'Abs\(vector\(.{1,2}?\)\)'
                m2 = re.findall(p2, str(expr2))
                if len(m2) == 1:
                    new_expr2 = expr2
                    m2 = m2[0]
                    m2 = sympify(m2)
                    name2 = m2.args[0].args[0]
                    name2 = str('Abs_') + str(name2)
                    name2 = sympify(name2)
                    new_expr2 = new_expr2.subs({m2: name2})
                    solutions2 = solve(new_expr2, name2)
                    if len(solutions2) == 1:
                        solution2 = solutions2[0]
                        xiangs2 = vector_xiangs(solution2)
                        if not xiangs2:
                            answer[str(name2)] = solution2
                            veqs.append([eq[1], eq[2]])
                        else:
                            veqs.append([eq[1], eq[2]])
                    else:
                        veqs.append([eq[1], eq[2]])
                else:
                    veqs.append([eq[1], eq[2]])
                veqs.append([eq[0], eq[1]])
            else:
                if isinstance(eq[1], (list, tuple)):
                    expr = eq[0]
                    p = r'vector\(.{1,2}?\)'
                    m = re.findall(p, str(expr))
                    if len(m) == 1:
                        m = m[0]
                        m = sympify(m)
                        name = m.args[0]
                        if len(str(name)) != 2:
                            name = str('Axis_') + str(name)
                            answer[name] = eq[1]
                        else:
                            veqs.append(eq)
                    else:
                        veqs.append(eq)
                elif str(eq[0].func) == str('interangle'):
                    vector_a, vector_b = eq[0].args
                    vector_a_name = vector_a.args[0]
                    vector_b_name = vector_b.args[0]
                    name1 = str('CAngle_') + str(vector_a_name) + str(vector_b_name)
                    name2 = str('CAngle_') + str(vector_b) + str(vector_a_name)
                    value = cos(eq[1])
                    answer[name1] = value
                    answer[name2] = value
                else:
                    expr = eq[0] - eq[1]
                    p = r'Abs\(vector\(.{1,2}?\)\)'
                    m = re.findall(p, str(expr))
                    if m:
                        if len(m) == 1:
                            new_expr = expr
                            m = m[0]
                            m = sympify(m)
                            name = m.args[0].args[0]
                            name = str('Abs_') + str(name)
                            name = sympify(name)
                            new_expr = new_expr.subs({m: name})
                            solutions = solve(new_expr, name)
                            if len(solutions) == 1:
                                solution = solutions[0]
                                xiangs = vector_xiangs(solution)
                                if not xiangs:
                                    answer[str(name)] = solution
                                    veqs.append(eq)
                                else:
                                    veqs.append(eq)
                        else:
                            veqs.append(eq)
                    else:
                        veqs.append(eq)
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


class XLBelongUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 1
        assert isinstance(args[0], BaseBelong)
        target = args[0].var
        target_interval = args[0].interval
        left, right, lopen, ropen = target_interval.args
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        if not left.is_infinite:
            if lopen:
                veqs.append([target, '>', left])
            else:
                veqs.append([target, '>=', left])
        if not right.is_infinite:
            if lopen:
                veqs.append([target, '<', right])
            else:
                veqs.append([target, '<=', right])
        answer['Vequations'] = veqs
        self.output.append(BaseShuLieValue(answer))
        return self


class XLUnitVectorsUpdate(BaseFunction):
    """
    已知\\overrightarrow {a}、\\overrightarrow {b}均为单位向量,它们的夹角为60°,
    那么|\\overrightarrow {a}+3\\overrightarrow {b}|=(  )
    """
    def solver(self, *args):
        vector_a = sympify(args[0].value[0])
        vector_b = sympify(args[0].value[1])
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append([Abs(vector_a), 1])
        veqs.append([Abs(vector_b), 1])
        answer = {'Vequations': veqs}
        # vector_a_name = vector_a.args[0]
        # vector_a_Abs_name = str('Abs_') + str(vector_a_name)
        # vector_b_name = vector_b.args[0]
        # vector_b_Abs_name = str('Abs_') + str(vector_b_name)
        # answer = {}
        # answer[vector_a_Abs_name] = 1
        # answer[vector_b_Abs_name] = 1
        self.output.append(BaseVectorValue(answer))
        return self


class XLUnitVectorsChuiZhiUpdate(BaseFunction):
    """
    已知\\overrightarrow{a}与\\overrightarrow{b}为两个垂直的单位向量,k为实数,
    若向量\\overrightarrow{a}+\\overrightarrow{b}与向量k\\overrightarrow{a}-\\overrightarrow{b}垂直,则k=().
    """
    def solver(self, *args):
        vector_a = sympify(args[0].value)
        vector_b = sympify(args[1].value)
        vector_a_name = vector_a.args[0]
        vector_a_abs_name = str('Abs_') + str(vector_a_name)
        vector_b_name = vector_b.args[0]
        vector_b_abs_name = str('Abs_') + str(vector_b_name)
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        answer[vector_a_abs_name] = 1
        answer[vector_b_abs_name] = 1
        veqs.append([vector_a * vector_b, S.Zero])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


class XLUnitVectorsJiaJiaoUpdate(BaseFunction):
    def solver(self, *args):
        vector_a = sympify(args[0].value[0])
        vector_b = sympify(args[0].value[1])
        du = args[1].sympify()
        du = du.args[0]
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append([Abs(vector_a), 1])
        veqs.append([Abs(vector_b), 1])
        left = vector_a * vector_b / (Abs(vector_a) * Abs(vector_b))
        right = cos(du / 180 * pi)
        veqs.append([left, right])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


class XLVectorJiaJiaoUpdate(BaseFunction):
    def solver(self, *args):
        vector_a = sympify(args[0].value)
        vector_b = sympify(args[1].value)
        du = args[2].sympify()
        du = du.args[0]
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
            left = vector_a * vector_b / (Abs(vector_a) * Abs(vector_b))
            right = cos(du / 180 * pi)
            veqs.append([left, right])
        else:
            veqs = []
            left = vector_a * vector_b / (Abs(vector_a) * Abs(vector_b))
            right = cos(du / 180 * pi)
            veqs.append([left, right])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 两个向量的夹角更新
class XLVectorsJiaJiaoUpdate(BaseFunction):
    """
    已知向量\\overrightarrow{a},\\overrightarrow{b}夹角为45°,|\\overrightarrow{a}|=1,|2\\overrightarrow{a}-\\overrightarrow{b}|=\\sqrt{10},则|\\overrightarrow{b}|=().
    """
    def solver(self, *args):
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        if len(args) == 2:
            vector_a = sympify(args[0].value[0])
            vector_b = sympify(args[0].value[1])
            if isinstance(args[1], BaseDu):
                du = args[1].sympify()
                du = du.args[0]
                right = cos(du / 180 * pi)
            else:
                f_du = args[1].sympify()
                right = cos(f_du)
        elif len(args) == 3:
            vector_a = sympify(args[0].value)
            vector_b = sympify(args[1].value)
            if isinstance(args[2], BaseDu):
                du = args[2].sympify()
                du = du.args[0]
                right = cos(du / 180 * pi)
            else:
                f_du = args[2].sympify()
                veqs.append([f_du, ">=", S.Zero])
                veqs.append([f_du, "<=", pi])
                right = cos(f_du)
        else:
            raise Exception("to do")
        vector_a_name = vector_a.args[0]
        vector_b_name = vector_b.args[0]
        answer = {}
        name = str('CAngle_')
        name1 = name + str(vector_a_name) + str(vector_b_name)
        name2 = name + str(vector_b_name) + str(vector_a_name)
        answer[name1] = right
        answer[name2] = right
        left = vector_a * vector_b / (Abs(vector_a) * Abs(vector_b))
        veqs.append([left, right])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 两组向量夹角相等更新
class XLVectorsEqualVectorsJiaJiaoUpdate(BaseFunction):
    """
    平面向量\\overrightarrow a = (1,2) ,\\overrightarrow b = (4,2),且m\\overrightarrow a + \\overrightarrow b
    与\\overrightarrow a 的夹角等于m\\overrightarrow a + \\overrightarrow b 与\\overrightarrow b 的夹角,则m =  ()
    """
    def solver(self, *args):
        if len(args) == 4:
            vector_a = sympify(args[0].value)
            vector_b = sympify(args[1].value)
            vector_c = sympify(args[2].value)
            vector_d = sympify(args[3].value)
        else:
            raise Exception("to do")
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append([vector_a * vector_b / (Abs(vector_a) * Abs(vector_b)),
                     vector_c * vector_d / (Abs(vector_c) * Abs(vector_d))])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 两个向量的夹角的余弦值更新
class XLVectorsJiaJiaoCosUpdate(BaseFunction):
    def solver(self, *args):
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        if len(args) == 2:
            vector_a = sympify(args[0].value[0])
            vector_b = sympify(args[0].value[1])
            value = args[1].sympify()
        elif len(args) == 3:
            vector_a = sympify(args[0].value)
            vector_b = sympify(args[1].value)
            value = args[2].sympify()
        else:
            raise Exception("to do")
        vector_a_name = vector_a.args[0]
        vector_b_name = vector_b.args[0]
        answer = {}
        name = str('CAngle_')
        name1 = name + str(vector_a_name) + str(vector_b_name)
        name2 = name + str(vector_b_name) + str(vector_a_name)
        answer[name1] = value
        answer[name2] = value
        left = vector_a * vector_b / (Abs(vector_a) * Abs(vector_b))
        veqs.append([left, value])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 非零向量 \\overrightarrow{m},\\overrightarrow{n}
class XLNotZeroVectorsUpdate(BaseFunction):
    """
    已知非零向量\\vec{m},\\vec{n} 满足|4\\vec{m}|=|3\\vec{n}|,\\vec{m}和\\vec{n}的夹角的余弦值为\\frac{1}{3}.
    若\\vec{n}⊥(t\\vec{m}+\\vec{n}), 则实数t的值为 ( )
    """
    def solver(self, *args):
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        if len(args) == 1:
            vector_a = sympify(args[0].value[0])
            vector_b = sympify(args[0].value[1])
        elif len(args) == 2:
            vector_a = sympify(args[0].value)
            vector_b = sympify(args[1].value)
        else:
            raise Exception("to do")
        vector_a_name = vector_a.args[0]
        vector_b_name = vector_b.args[0]
        answer = {}
        name = str('Abs_')
        vector_a_value = name + str(vector_a_name)
        vector_a_value = sympify(vector_a_value)
        vector_b_value = name + str(vector_b_name)
        vector_b_value = sympify(vector_b_value)
        veqs.append([vector_a_value, "!=", 0])
        veqs.append([vector_b_value, "!=", 0])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        return self


# 在\\triangle ABC中,AB=2,AC=3,\\overrightarrow{AB}•\\overrightarrow{BC}=2,则|\\overrightarrow{BC}|= ()
class XLTriangleUpdate(BaseFunction):
    def solver(self, *args):
        san_jiao_xing = args[0].name
        v_triangle = BaseVectorTriangle(san_jiao_xing)
        self.output.append(v_triangle)
        return self


# 在\\triangle ABC中,AB=2,AC=3,\\overrightarrow{AB}•\\overrightarrow{BC}=2,则|\\overrightarrow{BC}|= ()
class XLTriangleEqsUpdate(BaseFunction):
    def solver(self, *args):
        eqs = args[0].sympify()
        v_triangle = self.search('vTriangle')
        for eq in eqs:
            v_triangle.vEqs.append(eq)
        return self


class XLPointsUpdate(BaseFunction):
    def solver(self, *args):
        return self


class VectorsInterAngle(BaseFunction):
    def solver(self, *args):
        vector_a = sympify(args[0].value)
        vector_b = sympify(args[1].value)
        du = sympify(args[2].value)
        du = du.args[0]
        angle = symbols('angle')
        answer = {angle: [vector_a, vector_b, du]}
        self.output.append(BaseSymbolValue(answer))
        return self


class WhatTriangle(BaseFunction):
    def solver(self, *args):
        triangle = sympify(args[0].name)
        answer = {'tri': [triangle]}
        self.output.append(BaseSymbolValue(answer))
        return self


class TriangleEqs(BaseFunction):
    def solver(self, *args):
        _input = args[1].sympify()
        answer = {'sides': [], 'angle': [], 'Abs': []}
        for item in _input:
            if str(item[0]) in ['a', 'b', 'c', 'line(AB)', 'line(BA)', 'line(AC)', 'line(CA)', 'line(BC)', 'line(CB)']:
                answer['sides'].append([item[0], item[1]])
            elif str(item[0]) in ['A', 'B', 'C']:
                if str(item[1].func) == 'd':
                    answer['angle'].append([str(item[0]), item[1].args[0]])
                else:
                    answer['angle'].append([str(item[0]), item[1]])
            elif str(item[0].func) == 'Angle':
                if len(str(item[0].args[0])) == 1:
                    k = item[0].args[0]
                else:
                    k = sympify(str(item[0].args[0])[1])
                if str(item[1].func) == 'd':
                    v = item[1].args[0]
                else:
                    v = item[1]
                answer['angle'].append([str(k), v])
            elif isinstance(item[0], Abs):
                answer['Abs'] = item[1]

        self.output.append(BaseSymbolValue(answer))
        return self


class TriangleVectorEqs(BaseFunction):
    def solver(self, *args):
        _input = args[1].sympify()
        answer = {'sides': [], 'Arith': []}
        for item in _input:
            if str(item[0].args[0].func) == 'distance':
                k = str(item[0].args[0].args[0]) + str(item[0].args[0].args[1])
                answer['sides'].append([k, item[1]])
            elif isinstance(item[0], Abs):
                k = str(item[0].args[0].args[0])
                answer['sides'].append([k, item[1]])
            elif isinstance(item[0], Mul):
                answer['Arith'].append([item[0], item[1]])

        self.output.append(BaseSymbolValue(answer))

        return self


class XLJiaJiaoUpdate001(BaseFunction):
    def solver(self, *args):
        vector_a = sympify(args[0].value[0])
        vector_a_name = vector_a.args[0]
        vector_b = sympify(args[0].value[1])
        vector_b_name = vector_b.args[0]
        du = args[1].sympify()
        du = du.args[0]
        answer = {}
        angle_vector_a_b_name = str('Angle_') + str(vector_a_name) + str(vector_b_name)
        angle_vector_b_a_name = str('Angle_') + str(vector_b_name) + str(vector_a_name)
        answer[angle_vector_a_b_name] = du
        answer[angle_vector_b_a_name] = du
        self.output.append(BaseVectorValue(answer))
        return self


# 且A、B、C三点共线
class XLSanDianGongXianUpdate(BaseFunction):
    """
    已知向量\\overrightarrow{OA}=(k,12),\\overrightarrow{OB}=(4,5),\\overrightarrow{OC}=(-k,10),且A,B,C三点共线,则k=
    """
    def solver(self, *args):
        left, middle, right = args[0].sympify()
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        vector_a = str("vector(") + str(left) + str(middle) + str(")")
        vector_b = str("vector(") + str(left) + str(right) + str(")")
        vector_a = sympify(vector_a)
        vector_b = sympify(vector_b)
        g1 = sympify('g1')
        veqs.append([vector_a, g1 * vector_b])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        self.label.add("三点共线")
        self.steps.append(["", "∵ %s, %s, %s三点共线" % (new_latex(left), new_latex(middle), new_latex(right))])
        self.steps.append(["", "∴ %s" % BaseEq([vector_a, g1 * vector_b]).printing()])
        return self


if __name__ == '__main__':
    pass
